// 封装axios类
import axios from 'axios'
import type { AxiosInstance } from 'axios'
// 导入自定义接口
import type { RequestConfig } from './type'

import { ElLoading } from 'element-plus'
import { ElMessage } from 'element-plus'
import type { ILoadingInstance } from 'element-plus/lib/el-loading/src/loading.type'
import type { IMessageHandle } from 'element-plus/lib/el-message/src/types'

import { getItem } from '@/utils/storage'

// 设置初始logding,message的值
const DEFAUL_LOADING = true
const DEFAUL_MESSAGE = true

/**
 * 封装Request类
 * @showLoading ElLoading显示隐藏默认显示
 * @showMessage ElMessage显示隐藏默认显示
 * @returns {Promise}
 */

class Request {
  instance: AxiosInstance
  showLoading: boolean
  loading?: ILoadingInstance
  showMessage: boolean
  message?: IMessageHandle

  constructor(config: RequestConfig) {
    this.instance = axios.create(config)

    this.showLoading = config.showLoading ?? DEFAUL_LOADING
    this.showMessage = config.showMessage ?? DEFAUL_MESSAGE
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config: any) => {
        if (this.showLoading) {
          this.loading = ElLoading.service({
            lock: true,
            text: 'Loading......',
            background: 'rgba(0,0,0,0.3)'
          })
        }
        const token = getItem('token')
        if (token) {
          config.headers.Authorization = `Bearer ${token}`
        }
        return config
      },
      (err) => {
        return err
      }
    )
    // 响应拦截器
    this.instance.interceptors.response.use(
      (res) => {
        // 移除loading
        this.loading?.close()
        const data = res.data
        // 判断res是否成功
        if (data.code === '0') {
          if (this.showMessage) {
            this.message = ElMessage({
              message: data.msg,
              type: 'success'
            })
          }
        } else {
          this.message = ElMessage.error(data.msg)
        }

        return data
      },
      (err) => {
        this.loading?.close()
        return err
      }
    )
  }

  request<T = any>(config: RequestConfig): Promise<T> {
    if (config.showMessage === false) {
      this.showMessage = false
    }
    return new Promise((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 设置为true，不影响下一次请求
          this.showLoading = DEFAUL_LOADING
          this.showMessage = DEFAUL_MESSAGE
          resolve(res)
        })
        .catch((err) => {
          // 设置为true，不影响下一次请求
          this.showLoading = DEFAUL_LOADING
          this.showMessage = DEFAUL_MESSAGE
          reject(err)
          return err
        })
    })
  }
  get<T = any>(config: RequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }

  post<T = any>(config: RequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'POST' })
  }

  delete<T = any>(config: RequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'DELETE' })
  }

  patch<T = any>(config: RequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'PATCH' })
  }
}

export default Request
